package com.eric.text;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import org.jsoup.nodes.Document;

import com.eric.Config;
import com.eric.Config.DOC_PART;
import com.eric.utils.DictionaryUtils;
import com.eric.utils.ListUtils;
import com.eric.utils.Reader;

public abstract class AbstractTextWorker implements TextWorker {

	protected Object input;

	protected String text;

	protected String title;

	protected Document doc;

	protected DOC_PART docPart = Config.DOC_PART.DOC;

	protected boolean removeStopWords = true; // 默认删除停用词

	protected boolean init = false;

	protected List<String> result;

	protected static Set<String> customWords = new HashSet<>();

	protected static List<String> contextWords;

	protected static List<String> stopWords = new ArrayList<>();

	protected int charNum;

	protected int topN = 20;

	protected int sumNum = 200;

	protected abstract void initThis();

	public AbstractTextWorker(Object input) {
		this.input = input;
		doc = Reader.read2doc(input);
		result = new ArrayList<>();
		contextWords = new ArrayList<>();

		if (customWords.size() == 0)
			DictionaryUtils.addKeywordsFromUrl(customWords);// 需要先根据原始DOC把关键词加入
		if (stopWords.size() == 0)
			stopWords = Reader.read2List(Config.STOP_WORDS);
		title = doc.title();
		text = doc.body().text();
		charNum = text.length();
	}

	public String text() {
		return text;
	}

	@Override
	/**
	 * 通用init函数，针对输入进行判断等
	 */
	public void init() {
		// String inputType = Reader.inputType();
		//
		// if (docPart.equals(Config.DOC_PART.DOC)) {// 默认是Document
		// text = doc.text();
		// } else if (docPart.equals(Config.DOC_PART.ANCHOR)) {
		// StringBuilder sb = new StringBuilder();
		// for (String s : IR.anchors(doc.select("a"))) {
		// sb.append(s);
		// sb.append(System.lineSeparator());
		// }
		// text = sb.toString();
		// } else if (docPart.equals(Config.DOC_PART.ARTICLE)) {//
		// 仅对文章内容进行分词（不包含列表文字等等）
		// if (inputType.equals("doc")) {
		// text = IR.text(doc, true);
		// } else {// 输入的是字符串
		// text = doc.text();
		// }
		// }
	}

	public List<String> result() {
		return result;
	}

	public void docPart(Config.DOC_PART docPart) {
		this.docPart = docPart;
	}

	public void keepStopWords() {
		removeStopWords = false;
	}

	/**
	 * 从分词结果中删除停用词
	 * 
	 * @param result
	 */
	public void removeStopWords(List<String> result, List<String> stops) {
		result.removeAll(stops);
	}

	/**
	 * 判断字符是否接受，可用来剔除一些无意义，但不在stopworlds里面的
	 * 
	 * @param s
	 * @return true：如果通过所有判断（分隔符，货币等其他符号，空，tab，单个字母和数字）<br>
	 *         false：有任何一项没有通过
	 */
	public boolean acceptedText(String s) {
		if (s.matches(Config.REGEX_CN_CHAR + "*")// 中文字符
				|| s.matches(Config.REGEX_EN_CHAR + "*")// 西文字符
		)
			return true;
		else
			return false;
	}

	public void topN(int topN) {// 针对关键词提取，设置提取数量，默认是20
		this.topN = topN;
	}

	public void sumNum(int sumNum) {// 针对摘要提取，设置提取字数，默认是200
		this.sumNum = sumNum;
	}

	public String title() {
		return doc.title();
	}

	public abstract List<String> getContext();

	/**
	 * 返回数据格式：新闻:频道=2
	 * 
	 * @return
	 */
	public Map<Object, Integer> correlatedWords() {
		Map<Object, Integer> map = ListUtils.countDistinct(getContext());
		Map<Object, Integer> map2 = new HashMap<>();
		for (Entry<Object, Integer> entry : map.entrySet()) {
			if (entry.getValue() > Config.KW_PAIR_SUPPORT // 支持度
					&& ((String) entry.getKey()).contains(Config.KW_PAIR_SEPARATOR))
				map2.put(entry.getKey(), entry.getValue());
		}
		return map2;
	}

	public List<String> newKeywordCandidates(List<String> list) {
		List<String> list2 = new ArrayList<>();
		for (String s : list) {
			String ns = s.substring(0, s.indexOf("="));
			String[] ss = ns.split(":");
			for (int i = 0; i < ss.length; i++) {
				if (ss[i].length() == 1) {
					list2.add(ns);
					break;
				}
			}
		}
		return list2;
	}
}
